//
//  AppDelegate.swift
//  C004_test_optional
//
//  Created by yao_yu on 15/5/18.
//  Copyright (c) 2015年 yao_yu. All rights reserved.
//

import UIKit

class CSDN{
    var name:String?
    lazy var description:()->() = {[unowned self] in
        self.print()
    }
    func print(){
        Swift.print("闭包调用函数")
    }
    init(name:String?){
        self.name = name
    }
    deinit{
        Swift.print("内存将要释放")
    }
}


/// SLLayoutItem
protocol SLLayoutItem
{
    /// For items in an HGroup, the width as a percentage of the parent's width, for items in a VGroup, the height as a percentage of the parent's height
    /// If set to nil, Shinpuru Layout treats this like a standard UIView and automatically sets percentage itself
    var percentageSize: CGFloat? {get set}
    
    /// If percentage is nil, optional explicit size allows the item's width or height to be set in points
    var explicitSize: CGFloat? {get set}
}



/// Base Class
class SLGroup: SLLayoutItem
{
    var percentageSize: CGFloat?
    var explicitSize: CGFloat?
    
    private var childPercentageSizes = [CGFloat]()
    private var totalExplicitSize: CGFloat = 0
    
    typealias LayoutMetrics = (childPercentageSizes: [CGFloat], totalExplicitSize: CGFloat)
    typealias ChildMetric = (origin: CGFloat, size: CGFloat)
    
    func addSubview(view: AnyObject)
    {
        children.append(view)
    }
    
    var children: [AnyObject] = [AnyObject]()
        {
        didSet
        {
            
        }
    }
    
    
    
    var margin: CGFloat = 0
        {
        didSet
        {

        }
    }
    
    /// Returns a LayoutMetrics instance containing the percemtage sizes for each child and the total of the
    /// explicit sizes.
    class func calculateLayoutMetrics(children: [AnyObject]) -> LayoutMetrics
    {
        let bbb =  children.filter({ self.hasExplicitSize($0) })
        print(bbb)
        let totalExplicitSize = children.filter({ self.hasExplicitSize($0) }).reduce(CGFloat(0), combine: {$0 + ($1 as! SLLayoutItem).explicitSize!});
        
        let totalPercentages = children.filter({ self.hasPercentage($0) }).reduce(CGFloat(0), combine: {$0 + ($1 as! SLLayoutItem).percentageSize!})
        
        let defaultComponentPercentage = (CGFloat(100) - totalPercentages) / CGFloat(children.filter({ !self.hasPercentage($0) && !self.hasExplicitSize($0) }).count)
        
        let childPercentageSizes = children.map({ self.hasPercentage($0) ? ($0 as! SLLayoutItem).percentageSize! : defaultComponentPercentage })
        
        return (childPercentageSizes, totalExplicitSize)
    }
    
    
    
    /// Returns an array of ChildMetric instances that define absolute position and width
    /// to fit within totalExplicitSize
    class func calculateChildMetrics(children children: [AnyObject], childPercentageSizes: [CGFloat], availableSize: CGFloat, totalExplicitSize: CGFloat) -> [ChildMetric]
    {
        var currentOrigin: CGFloat = 0
        
        let returnArray = zip(children, childPercentageSizes).map
            {
                (child, childPercentage) -> ChildMetric in
                let percentageWidth = childPercentage / 100 * (availableSize - totalExplicitSize)
                let componentWidth: CGFloat = SLGroup.hasExplicitSize(child) ? (child as! SLLayoutItem).explicitSize! : percentageWidth
                let previous = currentOrigin
                currentOrigin += componentWidth
                
                return ChildMetric(origin: previous, size: componentWidth)
        }
        
        return returnArray
    }
    
    class func hasExplicitSize(value: AnyObject) -> Bool
    {
        return (value as? SLLayoutItem)?.explicitSize != nil && !hasPercentage(value)
    }
    
    class func hasPercentage(value: AnyObject) -> Bool
    {
        return (value as? SLLayoutItem)?.percentageSize != nil
    }
}

class SLHGroup: SLGroup {
}



@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    var instance:CSDN? = CSDN(name:"hello hwc")

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        
        let hGroup = SLGroup()
        hGroup.percentageSize = 100
        
        for _ in 1..<5 {
            let agroup = SLGroup()
            agroup.percentageSize = 20
            hGroup.addSubview(agroup)
        }
 
        instance?.description()
        instance = nil
        
        SLGroup.calculateLayoutMetrics(hGroup.children)
        
        return true
    }

    func applicationWillResignActive(application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(application: UIApplication) {
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


}

